package hihocode;


import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class EscapeMaze1328 {

	private static final char OBSTACLE = '#';
	
	public static final int[][] dir = {{0, -1}, {-1, 0}, {0, 1}, {1, 0}};
	private static final int MAX = 100; 
	
	private int minMinute = Integer.MAX_VALUE;
	
	private int rows, columns; 
	private char[][] maze = new char[MAX][MAX];
	
	private boolean[][][] visited = new boolean[MAX][MAX][35];
	
	//这个题目的输入范围有点大，行和列的最大值为100
	public static void main(String[] args) {
		EscapeMaze1328 object = new EscapeMaze1328();
		object.getRes();
	}
	
	
	public void getRes(){
		Scanner scanner = new Scanner(System.in);
		int k;
		while(scanner.hasNext()){
			rows = scanner.nextInt();
			columns = scanner.nextInt();
			k = scanner.nextInt();
			int startX = scanner.nextInt(), startY = scanner.nextInt();
			int endX = scanner.nextInt(), endY = scanner.nextInt();
			minMinute = Integer.MAX_VALUE;
			for (int i = 0; i < rows; i++) {
				String string = scanner.next();
				maze[i] = string.toCharArray();
			}
			for (int i = 0; i < k; i++) {
				int x = scanner.nextInt();
				int y = scanner.nextInt();
				maze[x][y] = (char)('a' + i);
			}
			bfs(startX, startY, endX, endY);
			if(minMinute == Integer.MAX_VALUE){
				System.out.println(-1);
			}else{
				System.out.println(minMinute);
			}
		}
		scanner.close();
	}
	
	class Node{
		int x, y, key, step;
		Node(){
		}
		Node(int x, int y){
			this.x = x;
			this.y = y;
		}
	}
	
	//Runtime 2012ms  内存 25MB
	public void bfs(int x, int y, int endX, int endY){
		Node node = new Node();
		node.x = x; node.y = y;
		Queue<Node> queue =  new LinkedList<>();
		queue.add(node);
		visited[x][y][0] = true;
		for (int i = 0; i < rows; i++) {
			for (int j = 0; j < columns; j++) {
				for (int k = 0; k < visited[0][0].length; k++) {
					visited[i][j][k] = false;
				}
			}
		}
		while(!queue.isEmpty()){
			node = queue.poll();
			if(node.x == endX && node.y == endY){
				minMinute = node.step;
				return;
			}
			for(int i = 0; i < dir.length; i++){
				int curX = node.x + dir[i][0];
				int curY = node.y + dir[i][1];
				if(curX < 0 || curX >= rows || curY < 0 || curY >= columns || maze[curX][curY] == OBSTACLE){
					continue;
				}
				if(visited[curX][curY][node.key]){
					continue;
				}
				Node next = new Node(curX, curY);
				next.key = node.key;
				if(maze[curX][curY] >= 'A' && maze[curX][curY] <= 'J') {
                    int c = maze[curX][curY] - 'A';
                    if( (next.key & (1 << c)) != 0) {
                        visited[curX][curY][next.key] = true;
                        next.step = node.step + 1;
                        queue.add(next);
                    }
                }else if(maze[curX][curY] >= 'a' && maze[curX][curY] <= 'j') {
                    int c = maze[curX][curY] - 'a';
                    next.key |= (1 << c);
                    if(!visited[curX][curY][next.key]) {
                    	visited[curX][curY][next.key] = true;
                    	next.step = node.step + 1;
                    	queue.add(next);
                    }
                }else {
                	visited[curX][curY][next.key] = true;
                	next.step = node.step + 1;
                	queue.add(next);
                }
			}
		}
	}
}
